package com.jy.task.fileoper;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import com.jy.common.utils.base.Tools;
import com.jy.common.utils.base.UuidUtil;
import com.jy.entity.filemanager.TSFile;

public class TcpClient {
	private FTPClient ftp;

	private String remoteUrlStr;
	private String localDirStr;
	private List<TSFile> fileStr;
	private String fileName;// 文件名
	private String extenName;// 扩展名
	private Date startDate;
	private Integer isSubFile;

	private String path;
	private String addr;
	private int port;
	private String username;
	private String password;

	private Date newDate;// 最新文件时间

	public TcpClient(String remoteUrl, String localDir, String fileName,
			String extenName, Date startDate, Integer isSubFile, String path,
			String addr, int prot, String username, String password) {
		this.remoteUrlStr = remoteUrl;
		this.localDirStr = localDir;
		fileStr = new ArrayList<TSFile>();
		this.fileName = fileName;
		this.extenName = extenName;
		this.startDate = startDate;
		this.isSubFile = isSubFile;
		this.path = path;
		this.addr = addr;
		this.port = prot;
		this.username = username;
		this.password = password;
	}

	/**
	 * 
	 * @param path
	 *            上传到ftp服务器哪个路径下
	 * @param addr
	 *            地址
	 * @param port
	 *            端口号
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * @return
	 * @throws Exception
	 */
	public boolean connect() throws Exception {
		// System.err.println(">>" + path + " " + addr + " " + port + " "
		// + username + " " + password);
		boolean result = false;
		ftp = new FTPClient();
		int reply;
		ftp.connect(this.addr, this.port);
		ftp.login(this.username, this.password);
		ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
		reply = ftp.getReplyCode();
		if (!FTPReply.isPositiveCompletion(reply)) {
			ftp.disconnect();
			return result;
		}
		ftp.changeWorkingDirectory(this.path);
		ftp.enterLocalPassiveMode();
		ftp.setConnectTimeout(7200 * 1000);
		result = true;
		return result;
	}

	public boolean smbToftpDirectory(String remoteUrl, String localDir) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		boolean returnFlag = true;
		try {
			jcifs.Config.setProperty("jcifs.smb.client.responseTimeout",
					"1200000");
			jcifs.Config.setProperty("jcifs.smb.client.soTimeout", "1200000");
			SmbFile smbFile = new SmbFile(remoteUrl);
			if (!smbFile.exists()) {
				System.out.println("no such folder");
			} else {
				SmbFile[] files = smbFile.listFiles();
				boolean uploadFlag = true;
				for (SmbFile f : files) {
					if (!f.isDirectory()) {
						System.out.println(">>>>" + f.getName());
						String dateTime = simpleDateFormat.format(new Date(f
								.getDate()));
						setNewDate(simpleDateFormat.parse(dateTime));
						// 文件時間是否在规定范围
						if (compareToDate(simpleDateFormat.parse(dateTime),
								simpleDateFormat.parse(simpleDateFormat
										.format(this.startDate)))) {
							// 扩展名和名称
							if (!Tools.isEmpty(this.fileName)) {
								if (patternStr(f.getName())) {
									uploadFlag = smbToftp(f, localDir);
								}
							} else {
								uploadFlag = smbToftp(f, localDir);
							}

							// 单个文件上传错误 任务返回
							if (!uploadFlag) {
								boolean connFlg = false;
								Thread.sleep(5000);
								for (int i = 0; i < 3; i++) {
									connFlg = connect();
									// 休眠5秒
									Thread.sleep(5000);
									if (connFlg) {
										break;
									}
								}

								if (connFlg) {
									boolean newReturnFlag = smbToftp(f,
											localDir);
									if (newReturnFlag) {
										continue;
									} else {
										returnFlag = false;
										break;
									}
								} else {
									returnFlag = false;
									break;
								}
							}
						}

					} else {
						if (this.isSubFile == 1) {
							// smbToftp(f, localDir);
							smbToftpDirectory(remoteUrl + f.getName(), localDir
									+ f.getName());
						}
					}

				}
			}
		} catch (Exception e) {
			returnFlag = false;
			e.printStackTrace();

		} finally {

		}
		return returnFlag;
	}

	private void setNewDate(Date dateStr) {
		if (newDate != null) {
			if (compareToDate(dateStr, newDate)) {
				newDate = dateStr;
			}
		} else {
			newDate = dateStr;
		}
	}

	public Date getNewDate() {
		return newDate;
	}

	private boolean compareToDate(Date date1, Date date2) {
		if (date1.getTime() > date2.getTime()) {
			return true;
		}
		return false;
	}

	private boolean patternStr(String str) {
		String newString[] = (this.fileName).split(",");
		boolean rs = false;
		for (String reg : newString) {
			String regEx = reg.replace(".", "/").replace("?", ".?")
					.replace("*", ".*");
			Pattern pattern = Pattern.compile(regEx);
			Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
			Matcher matcher = pattern.matcher(str);
			rs = matcher.find();
			if (rs)
				break;
		}
		// 查找字符串中是否有匹配正则表达式的字符/字符串
		return rs;
	}

	private boolean getExFileName(SmbFile f, String localDir) {
		boolean uploadFlag = true;
		if (Tools.isEmpty(this.extenName)) {
			uploadFlag = smbToftp(f, localDir);
		} else {
			if (f.getName().contains(this.extenName)) {
				uploadFlag = smbToftp(f, localDir);
			}
		}
		return uploadFlag;
	}

	public Map smbTosmbMother() {
		Map<String, Object> returnMap = new HashMap<String, Object>();
		boolean updateFlag = smbToftpDirectory(this.remoteUrlStr,
				this.localDirStr);
		if (!updateFlag)
			newDate = null;
		// 上传失败
		if (!updateFlag) {
			returnMap.put("Msg", false);
		} else {
			returnMap.put("Msg", true);
		}
		return returnMap;
	}

	public List<TSFile> getFileList() {
		return fileStr;
	}

	/**
	 * 
	 * @param smbFile
	 *            文件file
	 * @param remoteUrl
	 *            目标路径
	 */
	private int index = 0;

	public Boolean smbToftp(SmbFile smbFile, String remoteUrl) {
		InputStream in = null;
		boolean uploadFlag = true;
		try {
			remoteUrl = new String(remoteUrl.getBytes("UTF-8"), "iso-8859-1");
			if (!ftp.isConnected()) {
				boolean connFlg = false;
				for (int i = 0; i < 10; i++) {
					connFlg = connect();
					// 休眠5秒
					Thread.sleep(5000);
					if (connFlg) {
						break;
					}
				}
				if (!ftp.isConnected())
					uploadFlag = false;
			}
			ftp.setControlEncoding("UTF-8");
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			CreateDirecroty(remoteUrl);
			// boolean flag = ftp.changeWorkingDirectory(remoteUrl);
			// System.out.println("localFile.getPath()" + remoteUrl);
			// if (!flag) {
			// // 创建上传的路径 该方法只能创建一级目录，在这里如果/home/ftpuser存在则可创建image
			// ftp.makeDirectory(remoteUrl);
			// ftp.changeWorkingDirectory(remoteUrl);
			// }
			if (!smbFile.isDirectory()) {
				if (!smbFile.exists()) {
					for (int i = 0; i < 10; i++) {
						smbFile.connect();
						if (smbFile.exists())
							break;
					}
				}
				in = new BufferedInputStream(new SmbFileInputStream(smbFile));
				String fileName = new String(smbFile.getName()
						.getBytes("UTF-8"), "iso-8859-1");
				index++;
				// System.out.println(">>>" + index + ">" + fileName);
				if (ftp.isConnected()) {
					boolean typeflag = ftp.storeFile(fileName, in);
					if (typeflag) {
						TSFile objFile = new TSFile();
						objFile.setId(UuidUtil.get32UUID());
						objFile.setFileName(smbFile.getName());
						fileStr.add(objFile);
					}
					System.out.println(">>>" + index + "    " + fileName
							+ "   " + typeflag);
				} else {
					return false;
				}
			}
		} catch (Exception e) {
			// closeFtp();
			uploadFlag = false;
			e.printStackTrace();
		} finally {
			try {
				if (!smbFile.isDirectory()) {
					in.close();
				}
			} catch (IOException e) {

				e.printStackTrace();

			}
		}
		return uploadFlag;
	}

	public void closeFtp() {
		if (ftp != null && ftp.isConnected()) {
			try {
				ftp.logout();
				ftp.disconnect();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public boolean CreateDirecroty(String remote) throws IOException {
		boolean success = true;
		String directory = remote + "/";
		// String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
		// 如果远程目录不存在，则递归创建远程服务器目录
		if (!directory.equalsIgnoreCase("/")
				&& !changeWorkingDirectory(new String(directory))) {
			int start = 0;
			int end = 0;
			if (directory.startsWith("/")) {
				start = 1;
			} else {
				start = 0;
			}
			end = directory.indexOf("/", start);
			String path = "";
			String paths = "";
			while (true) {
				String subDirectory = new String(remote.substring(start, end)
						.getBytes("UTF-8"), "iso-8859-1");
				path = path + "/" + subDirectory;
				if (!ftp.changeWorkingDirectory(path)) {
					if (makeDirectory(subDirectory)) {
						changeWorkingDirectory(subDirectory);
					} else {
						changeWorkingDirectory(subDirectory);
					}
				} else {
					changeWorkingDirectory(subDirectory);
				}
				paths = paths + "/" + subDirectory;
				start = end + 1;
				end = directory.indexOf("/", start);
				// 检查所有目录是否创建完毕
				if (end <= start) {
					break;
				}
			}
		}
		return success;
	}

	public boolean makeDirectory(String dir) {
		boolean flag = true;
		try {
			flag = ftp.makeDirectory(dir);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	// public boolean existFile(String path) throws IOException {
	// boolean flag = false;
	// FTPFile[] ftpFileArr = ftp.listFiles(path);
	// if (ftpFileArr.length > 0) {
	// flag = true;
	// }
	// return flag;
	// }

	public boolean changeWorkingDirectory(String directory) {
		boolean flag = true;
		try {
			flag = ftp.changeWorkingDirectory(directory);
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return flag;
	}

	public static void main(String[] args) throws Exception {

		/*
		 * boolean lianjie = connect("/text/", "192.168.0.50", 21, "ftpuser",
		 * "ftpuser");
		 * 
		 * smbToftpDirectory(
		 * "smb://administrator:CloudBim_403@192.168.0.13/test/", "/text/new/");
		 */

	}

}
